package com.ygqh.baby.service;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.model.*;
import com.ygqh.baby.model.wdt.qyb.PushOrderToWdtResult;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.wdtqyb.exception.WdtException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

public interface YgOrderService {

    List<YgOrder> find();

    int findCount();

    YgOrder findById(Long id);

    YgOrder findByOrderId(Long orderId);

    /**
     * 获取订单详情（运营后台）
     *
     * @param id 订单主键id
     * @return
     */
    YgOrder findOrderDetail(Long id);

    /**
     * 获取订单信息
     *
     * @param orderId 订单编号
     * @return
     */
    YgOrder findOrderDetailByOrderId(Long orderId);

    YgOrder findOrderDetailByOrderId(Long orderId, DataStatus status);

    int deleteSoft(Long[] orderIds, Long userid);

    int deleteSoft(Long orderId, Long userId);

    int save(YgOrder ygOrder);

    int update(YgOrder ygOrder);

    int updateByOrderId(YgOrder ygOrder);

    int updateByOrderId(YgOrder ygOrder, DataStatus status);

    int saveOrUpdate(YgOrder ygOrder);

    /**
     * 运营后台订单列表
     *
     * @param queryInfo
     * @param supplierId
     * @param orderId
     * @param payType
     * @param orderStatus
     * @param startDate
     * @param endDate
     * @param q
     * @param platform
     * @return
     */
    ResultSet<YgOrder> search(QueryInfo queryInfo, Long supplierId, Long orderId, PayType payType, OrderStatus orderStatus, Date startDate, Date endDate,
                              String q, String userName, String telPhone, String validOrder, String platform, String sourceCode, OrderType orderType, String productName);

    /**
     * 去结算页面
     *
     * @param skuIds
     * @param userId
     */
    Message toSettlementPage(Long[] skuIds, Long userId);

    Message toSettlementPage(Long[] skuIds, Long userId, Boolean distribution);

    /**
     * 提交订单
     *
     * @param userId
     * @param userName
     * @param userAddressId
     * @param couponDetailId
     * @param totalPrice
     * @param payType
     * @param sourceCode
     * @param accountPrice
     * @param formId
     * @param userRemark
     * @param expressCardId  包邮功能卡id
     * @param carList        购物车信息
     * @param platformNo
     * @param identityNo     收货人身份证号
     * @param salesPlatform  销售平台
     * @return
     */
    Message commitOrder(Long userId, String userName, Long userAddressId, Long couponDetailId, BigDecimal totalPrice, AppType appType, PayType payType,
                        String sourceCode, BigDecimal accountPrice, String formId, String userRemark, Long expressCardId, OrderType orderType,
                        List<YgShoppingCarModel> carList, String platformNo, String identityNo, SalesPlatform salesPlatform);


    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    Message saveMainOrder(YgUserAddress address, YgCouponDetail couponDetail, BigDecimal couponPrice, Long userId, String userName,
                          BigDecimal totalPrice, BigDecimal accountPrice, BigDecimal productPrice, BigDecimal manJianPrice, BigDecimal expPrice, BigDecimal newCustomDisPrice,
                          BigDecimal packDisPrice, BigDecimal groupDisPrice, BigDecimal bmdisPrice, AppType appType, PayType payType, String sourceCode,
                          List<YgShoppingCarModel> carList, List<YgShoppingCarModel> packs, String formId, Long groupBuyId, OrderType orderType, String userRemark,
                          YgCardCouponDetail expressCard, String platformNo, Boolean trustonerOrderFlag, Boolean reduceStockFlag, SalesPlatform salesPlatform);

    /**
     * 我的中订单列表
     *
     * @param userId
     * @param orderStatus
     * @return
     */
    @Deprecated
    List<YgOrderModel> findOrderList(QueryInfo queryInfo, Long userId, OrderStatus orderStatus);

    List<YgOrderModel> findOrderList(QueryInfo queryInfo, Long userId, OrderStatus orderStatus, String platformNo);

    /**
     * M站个人中心获取订单详情
     *
     * @param orderId
     * @param userId
     * @return
     */
    YgOrderInfoModel findOrderInfo(Long orderId, Long userId);

    /**
     * 验证优惠券
     *
     * @param couponDetail
     * @param productPrice
     * @param onlySpecial
     * @param carList
     * @param salesPlatform
     * @return
     */
    Message validateCoupon(YgCouponDetail couponDetail, BigDecimal productPrice, Boolean onlySpecial, List<YgShoppingCarModel> carList,
                           SalesPlatform salesPlatform);

    /**
     * 获取购物车中已选商品总额（含加价购）
     *
     * @param userId
     * @return
     */
    Map<String, BigDecimal> getProductPrice(List<YgShoppingCarModel> cars);

    /**
     * 获取运费
     *
     * @param productPrice
     * @return
     */
    BigDecimal getExpressPrice(BigDecimal productPrice, Long userId);

    BigDecimal getExpressPrice(BigDecimal productPrice, Long userId, SalesPlatform salesPlatform);

    /**
     * 获取满减金额
     *
     * @param productPrice
     * @param formId
     * @param userId
     * @return
     */
    Map<String, Object> getManJianPrice(BigDecimal productPrice, String formId, Long userId);

    /**
     * 支付成功后拆单操作
     *
     * @param orderId
     * @param totalPrice
     * @param payType
     * @throws WdtException
     */
    int splitOrder(Long orderId, BigDecimal totalPrice, PayType payType);

    /**
     * @param orderId
     * @param totalPrice
     * @param payType
     * @return int 返回类型
     * @throws @date 2017年9月8日 下午3:44:35
     * @Title: splitOrderV2
     * @author （guohao）
     * @version V1.0
     */
    int splitOrderV2(Long orderId, BigDecimal totalPrice, PayType payType);

    /**
     * 获取订单中商品评论的状态
     *
     * @param orderId
     * @param userId
     * @return
     */
    List<YgOrder4CommentModel> findWaitingComment(Long orderId, Long userId);

    /**
     * 未交易订单可以取消
     *
     * @param orderId
     * @param userId
     * @param userName
     * @param cancelReason
     * @return
     */
    int cancelOrder(Long orderId, Long userId, String userName, String cancelReason);

    /**
     * 获取不同状态下订单数量
     *
     * @param userId
     * @return
     */
    @Deprecated
    List<Map<String, Object>> findCountByOrderStatus(Long userId);

    List<Map<String, Object>> findCountByOrderStatus(Long userId, String platformNo);

    /**
     * 根据sourceCode 获取订单总金额
     *
     * @param fromCode
     * @return
     */
    YgCommissionOrderModel findOrderForBalance(String fromCode);

    /**
     * 定时任务取消超时订单
     *
     * @param orderIds
     * @param cancelReason
     * @return
     */
    int cancelOrderByTask(List<Long> orderIds, String cancelReason);

    /**
     * 获取创建订单后一小时未支付的订单
     *
     * @param limitTime 增量扫描时间间隔 单位 分钟
     * @return
     */
    List<YgOrder> findOrderForSendPayInvitation(Integer limitTime);

    /**
     * 获取此次作业时间内的所有订单
     *
     * @param limitTime 增量扫描时间间隔 单位 分钟
     * @return
     */
    List<YgOrder> findOrderForBalaceTask(Integer limitTime);

    /**
     * 获取所有超时支付的订单列表
     *
     * @param curretDate 小于 curretDate的订单
     * @return
     */
    List<YgOrder> findOrderIdForCancelTask(Date curretDate);

    /**
     * 订单发货七天后，订单自动更新为交易成功状态
     *
     * @param date 当前日期 -7
     */
    List<YgOrder> findOrder4SuccessTask(Date date);

    int orderStatusForSuccessTask(List<Long> orderIds);

    /**
     * 追踪物流信息（请求快递鸟接口）
     *
     * @param expCode
     * @param expNo
     */
    Message getLogisticsInfo(String expCode, String expNo);

    /**
     * 订单是否已付款
     *
     * @param orderId
     * @return
     */
    Boolean isPaid(Long orderId);

    /**
     * 订单数据导出
     *
     * @param productName
     */

    List<Map<String, Object>> getOrderReport(Date startDate, Date endDate, String userName, String sourceCode, String q, String orderStatus, String telPhone,
                                             Boolean validOrder, String productName);

    /**
     * 交易成功后7天如果用户没有评论，系统自动好评
     *
     * @param limitDate
     * @return
     */
    List<Comment4TaskModel> findProductComment4Task(Date limitDate);

    /**
     * 同步物流数据到本地订单 定时任务
     *
     * @param orderList
     * @param orderOidList
     * @return
     */
    int updateStatus4SendByTask(List<YgOrder> orderList, List<YgOrderDetail> sendDetailList);

    /**
     * 支付成功后处理业务
     *
     * @param paymentCode
     * @param transactionId
     * @param totalPrice
     * @param payType
     */
    void doBussness4PaySuccess(String paymentCode, String transactionId, BigDecimal totalPrice, AppType appType, PayType payType);

    /**
     * 订单中商品是否已经全部评论
     *
     * @param orderId
     * @return itemCount 订单商品种类， commentCount 以评论数量
     */
    Map<String, Long> orderIsComment(Long orderId);

    /**
     * 查找成交时间达到30天的订单
     *
     * @param startDate
     * @param endDate
     * @return
     */
    List<YgOrder> findOrderFor30Day(Date startDate, Date endDate);

    /**
     * 获取购物车中 新客优惠的价格，自选包优惠的价格
     *
     * @param list
     * @param userId
     * @param isValid
     * @param vip
     * @return newCustomDisPrice ;packDisPrice
     */
    Message getNewCusAndPackPrice(List<YgShoppingCarModel> list, Long userId, Boolean isValid);

    /**
     * 存在已支付订单
     *
     * @param id
     * @return
     */
    Boolean hasPayOrder(Long id);

    List<YgOrder> findCancelOrderForBalaceTask(Integer day);

    /**
     * 确认收货接口
     *
     * @param orderId
     * @param id
     * @return
     */
    Message confirmReceipt(Long orderId, Long userId);

    /**
     * 查询传入时间前一天的订单
     *
     * @return
     */
    List<YgOrder> selectIntervalOrder(Date date);

    /**
     * 获取为评论完成的订单数量
     *
     * @param userId
     * @return
     */
    @Deprecated
    int countUnCommentComplete(Long userId);

    int countUnCommentComplete(Long userId, String platformNo);

    /**
     * 保存代理订单
     *
     * @param orderlist
     * @return
     */
    Message saveImportOrder(List<YgOrder4ImportModel> agentOrderList, Long userId);

    /**
     * 按时间区间查询订单
     *
     * @param startDate
     * @param endDate
     * @param oStatus
     * @return
     */
    List<YgOrder> findByCreateTime(Date startDate, Date endDate, List<String> oStatus);

    List<YgOrder> findReturnOrderForBalaceTask(Integer day);

    /**
     * 补自选包数据使用，其他人不要调用
     *
     * @return
     */
    @Deprecated
    List<YgOrder> repairOrderDetailRemark();

    /**
     * 不要轻易使用，使用前看一下sql是否满足要求，最初只支持remark的更新
     *
     * @param detailList
     * @return
     */
    int updateDetailBatch(List<YgOrderDetail> packDetailList);

    /**
     * 查找该用户有效订单的第一单
     *
     * @param userId
     * @return
     */
    YgOrder findFirstOrder(Long userId, Date limitDate);

    List<YgOrder> findFirstOrderList(Date startDate, Date endDate);

    List<YgOrder> findReturnOrderForPreIncomeToBalance(Integer day);

    /**
     * 拼团订单提交
     *
     * @param skuList
     * @param id
     * @param userName
     * @param userAddressId
     * @param couponDetailId
     * @param totalPrice
     * @param payType
     * @param sourceCode
     * @param accountPrice
     * @param formId
     * @param groupId        拼团分组id
     * @param groupBuyId
     * @param orderType
     * @param userRemark
     * @param platformNo
     * @param identityNo     收件人身份证号
     * @param salesPlatform  销售平台
     * @return
     * @throws YgException
     */
    Message commitOrderPt(List<YgPtSkuInfo> skuList, Long id, String userName, Long userAddressId, Long couponDetailId, BigDecimal totalPrice, AppType appType,
                          PayType payType, String sourceCode, BigDecimal accountPrice, String formId, Long groupId, Long groupBuyId, OrderType orderType,
                          String userRemark, String platformNo, String identityNo, SalesPlatform salesPlatform) throws YgException;

    List<Map<String, Object>> getOrderLogisticsReport(Date startDate, Date endDate, String userName, String sourceCode, String q, String orderStatus,
                                                      String telPhone, Boolean validOrder);

    List<YgOrderDetail> findDetails(Long orderId);

    List<OrderNotPushModel> findOrderNotPush(Date limitDate);

    /**
     * @param queryInfo
     * @param waitingsend
     * @param userName
     * @return List<YgOrderModel> 返回类型
     * @throws @date 2017年7月5日 下午12:10:30
     * @Title: findOrderListByHeXiao
     * @Description: 获取核销列表页
     * @author （guohao）
     * @version V1.0
     */
    List<YgOrderModel> findOrderListByHeXiao(QueryInfo queryInfo, OrderStatus waitingsend, String userName);

    /**
     * 该用户是否存在有效核销订单
     *
     * @param @param  userId
     * @param @return 入参
     * @return Boolean 返回类型
     * @throws @date 2017年7月7日 下午4:03:34
     * @Title: hasHeXiaoOrder
     * @author （guohao）
     * @version V1.0
     */
    Boolean hasHeXiaoOrder(Long userId);

    YgOrder findLastOrder(OrderType orderType, Boolean paied);

    int closeOrderBySystem(Long orderId, String reason);

    /**
     * 不含明细
     *
     * @param orderId 入参
     * @return YgOrder 返回类型
     * @throws @date 2017年10月9日 下午5:08:36
     * @Title: getOrderByOrderId
     * @author （guohao）
     * @version V1.0
     */
    YgOrder getOrderByOrderId(Long orderId);

    /**
     * 导入第三方平台的订单
     *
     * @param agentOrderList
     * @param userId
     * @return
     */
    Message saveImportThirdOrder(List<YgOrder4ImportModel> agentOrderList, Long userId);

    /**
     * 根据商品名称导出已经支付的订单
     *
     * @param productName
     * @return
     */
    List<Map<String, Object>> selectOrderByProductName(String productName);

    List<String> getNoSendOrderListBySupplier(Long supplierId);

    /**
     * 外部商家发货
     *
     * @param ygLogistics
     * @return
     */
    Message updateLogistics(List<YgLogistics> ygLogistics);

    List<Map<String, Object>> getOrderDetailBySupplier(Long q, Date startDate, Date endDate, OrderStatus orderStatus, String telPhone, Long supplierId);

    ResultSet<YgOrder> searchBySupplier(QueryInfo queryInfo, String q, OrderStatus orderStatus, Date startDate, Date endDate, Long supplierId, String telPhone);

    List<YgOrder> searchOrderBySupplier(QueryInfo queryInfo, String q, OrderStatus orderStatus, Date startDate, Date endDate, Long supplierId, String telPhone);

    YgOrderInfoModel selectOrderDetailBySupplierOrderId(Long orderId, Long supplierId);

    /**
     * 外部商家发货发送获取用户OpenId
     *
     * @param log
     * @return
     */
    List<Map<String, Object>> selectOpenIdByOrder(List<YgLogistics> log);

    int selectReturnByOrder(Long supplierId, Long orderId, String skuCode);

    List<Long> findExitOrderIds(List<Long> orderIds);

    List<YgOrder> findByPaidTimeHasDetail(Date startDate, Date endDate, String sourceCode, OrderStatus... orderStatus);

    List<YgOrder> findByPaidTimeHasDetail(Date startDate, Date endDate, String sourceCode, Long supplierId, OrderStatus... orderStatus);

    List<YgOrder> findOrderDetailByOrderNoList(List<Long> orderNos);

    int saveOrderList(List<YgOrder> orderList);

    List<Map<String, Object>> getTotalPriceWithMonth(Long userId, Date startDate, Date endDate);

    List<YgOrder> findOrderDetailByReturn(Date startDate, Date endDate, String returnCode, ReturnType returnType, ReturnStatus... returnStatus);

    /**
     * 代理下单（不包含带有其他代理source的订单）
     *
     * @param checkTime
     * @param cancelTime
     * @param userId
     * @param orderStatus
     * @return
     */
    List<YgOrder> findAgentOrderByPaidTimeHasDetail(Date checkTime, Date cancelTime, Long id, OrderStatus... orderStatus);

    /**
     * 团成员下单（不包含带有其他代理source的订单）
     *
     * @param checkTime
     * @param cancelTime
     * @param userId
     * @param orderStatus
     * @return
     */
    List<YgOrder> findGroupMemberOrderByPaidTimeHasDetail(Date checkTime, Date cancelTime, String groupTag, OrderStatus... orderStatus);

    /**
     * 按订单号查询订单退款明细
     *
     * @param checkTime
     * @param cancelTime
     * @param orderIds
     * @param returnType
     * @param returnStatus
     * @return
     */
    List<YgOrder> findRODByOrderId(List<Long> orderIds, ReturnType returnType, ReturnStatus... returnStatus);

    List<YgOrder> findOrderBySendTime(Date startDate, Date endDate);

    int splitOrderV3(Long orderId, BigDecimal totalPrice, PayType payType, Date paidTime);

    /**
     * 根据父单id获取
     *
     * @param parentId
     * @return
     */
    List<YgOrder> findByParentId(Long parentId);

    /**
     * 将原用户订单转移到目标用户下
     *
     * @param sourceUserId
     * @param targetUserId
     * @return int    返回类型
     * @throws
     * @Title: transferOrder
     * @author （guohao）
     * @date 2018年5月10日 下午6:32:08
     * @version V1.0
     */
    int transferOrder(Long sourceUserId, Long targetUserId);

    /**
     * 按下单时间查询（含有明细）
     *
     * @param startDate
     * @param endDate
     * @param filterSourceList 过滤sourceCode集
     * @return
     */
    List<YgOrder> findByCreateTimeHasDetail(Date startDate, Date endDate, List<String> filterSourceList);

    Boolean isExist(Long orderId);

    int countDetailBySupplierId(Long orderId, Long supplierId);

    List<YgOrder> findOrderBySendTimeHasDetail(Date startDate, Date endDate, Long supplierId);

    int updateOrderSendStatus(Long orderId, Date sendTime);

    /**
     * 用户发货的第一单
     *
     * @param userId
     * @param limitDate
     * @return
     */
    YgOrder findFirstSendOrder(Long userId, Date limitDate, Long limitOrderId);

    List<YgOrder> findOrderBySendTimeHasDetail(Date startDate, Date endDate, Long supplierId, String... orderType);

    /**
     * 验证成长基金
     *
     * @param userId
     * @param accountPrice
     * @param totalPrice
     * @return
     */
    Message validateAccountPrice(Long userId, BigDecimal accountPrice, BigDecimal totalPrice);

    /**
     * 根据订单编号修改订单状态
     *
     * @param orderStatus
     * @param orderId
     * @return
     */
    int updateOrderStatusByOrderId(OrderStatus orderStatus, Long orderId);

    List<YgOrder> findByGroupBuyId(OrderStatus orderStatus, List<Long> groupBuyIdList);

    /**
     * 查询未发货订单
     *
     * @param queryInfo
     * @param startDate
     * @param endDate
     * @return
     */
    ResultSet<Map<String, Object>> selectNoSendOrderList(QueryInfo queryInfo,
                                                         Date startDate, Date endDate);

    /**
     * 查询未发货订单的明细
     *
     * @param queryInfo
     * @param supplierId
     * @param startDate
     * @param endDate
     * @return
     */
    ResultSet<Map<String, Object>> selectNoSendOrderDetail(QueryInfo queryInfo,
                                                           Long supplierId, Date startDate, Date endDate);

    int updateWdtCode(Long... orderIds);

    /**
     * 是否存在当前外部单号的订单  占用order中 sourceCode 字段
     *
     * @param outCode 外部单号
     * @return boolean
     */
    boolean existedByOutCode(String outCode);


    /**
     * 获取订单分享返利金额
     *
     * @param orderId 订单ID
     * @return BigDecimal
     */
    BigDecimal getTotalSharePrice(Long orderId);

    List<YgOrderInfoModel> findOrderInfoByPayTime(Date startTime, Date endTime, String platformNo);

    YgOrder findOrderDetailByOrderIdForThird(Long orderId);

    int updateWdtCodeBatch(List<PushOrderToWdtResult> successList);

    int updateWdtCode(PushOrderToWdtResult pushOrderToWdtResult);

    List<YgOrder> findOrderListByOrderIds(List<Long> orderIds);

    List<YgOrder> findOrderDetailBySupplier(Long supplierId, OrderDetailStatus orderDetailStatus);

    YgOrder findByReleateId(Long userBargainId, OrderType kanJia);

    Message saveZeroOrder(YgSkuInfo skuInfo, YgUserAddress address, String platformNo, AppType appType);

    List<YgOrder> findByPaidTime(Date startDate, Date endDate, String platformNo);
}
